`timescale 1ns/1ps
`default_nettype none

/* NOTE:
* - 将图像数据写入SDRAM
*/

//`define ENABLE_HUB_PORT_OFFSET
module rgb_pixel_save_top (
    // system signal
    input  wire         I_sclk,  // 125M
    input  wire         I_sdram_clk, // 150M
    input  wire         I_rst_n,
    // config
    input  wire [12:0]  I_cfg_win_pos_x,     // x坐标，有符号
    input  wire [11:0]  I_cfg_win_pos_y,     // y坐标，有符号
    input  wire [10:0]  I_cfg_win_col_num,   // 带载列数（宽度）
    input  wire [10:0]  I_cfg_win_row_num,   // 带载行数（高度）
    input  wire [1:0]   I_cfg_box_dir,       // 箱体方向
    input  wire [3:0]   I_cfg_sector_count,  // 多开数量
    input  wire [10:0]  I_cfg_sector_width,  // 每个"多开区域"宽度
    input  wire [7:0]   I_cfg_port_height,
    // port map
    output wire         O_port_map_rden,
    output wire [7:0]   O_port_map_addr,
    input  wire [15:0]  I_port_map_q,
    // row addr decoder
    output wire         O_decode_req,     // 行地址译码请求
    output wire [1:0]   O_decode_buf_sel, // SDRAM按帧分块选择
    output wire [9:0]   O_decode_row,     // 行号
    output wire [3:0]   O_decode_sector,  // 分区号
    input  wire         I_decode_done,    // 译码完成
    input  wire [20:0]  I_decode_addr,    // 译码结果

    output wire [9:0]   O_decode_col_addr,
    input  wire [9:0]   I_decode_col_addr,

    // input frame
    input  wire         I_frame_start,
    input  wire [1:0]   I_frame_id,  // 用于选定SDRAM存储区
    input  wire         I_frame_end,
    input  wire         I_row_end,
    input  wire         I_burst_start,
    input  wire [12:0]  I_burst_row,
    input  wire [12:0]  I_burst_col,
    input  wire         I_pixel_en,
    input  wire [7:0]   I_pixel_data,
    // sdram mux
    output wire         O_write_sdram_req,
    input  wire         I_write_sdram_ack,
    input  wire         I_write_sdram_irq,
    output wire         O_write_sdram_cs_n,
    output wire         O_write_sdram_ras_n,
    output wire         O_write_sdram_cas_n,
    output wire         O_write_sdram_we_n,
    output wire [1:0]   O_write_sdram_ba,
    output wire [10:0]  O_write_sdram_addr,
    output wire [31:0]  O_write_sdram_dq_out,
    input  wire [31:0]  I_write_sdram_dq_in,
    output wire         O_write_sdram_dq_oe,
    output wire [3:0]   O_write_sdram_dqm

);
//------------------------Parameter----------------------

//------------------------Local signal-------------------
// pixel_crop
wire        line_start;
wire        line_end;
wire [9:0]  line_num;
wire        pixel_valid;
wire [9:0]  pixel_col;
wire [23:0] pixel_gray;

wire        line_start_2;
wire        line_end_2;
wire [9:0]  line_num_2;
wire        pixel_valid_2;
wire [9:0]  pixel_col_2;
wire [23:0] pixel_gray_2;

// line output
wire        row_start;
wire [9:0]  row_num;
wire        row_ready;
wire        row_ack;
wire        pixel_req;
wire [23:0]  pixel_data;
wire [9:0]  pixel_addr;

// pixel_writer_top
wire        write_start;
wire        write_busy;
wire [20:0] write_addr;
wire [5:0]  write_len;
wire [23:0]  write_data;

// misc
wire [10:0] cfg_last_col;

wire        write_valid;
//------------------------Instantiation------------------
// pixel_crop
pixel_crop crop (/*{{{*/
    .I_sclk        ( I_sclk ),
    .I_rst_n       ( I_rst_n ),
    .I_cfg_pos_x   ( I_cfg_win_pos_x ),
    .I_cfg_pos_y   ( I_cfg_win_pos_y ),
    .I_cfg_col_num ( I_cfg_win_col_num ),
    .I_cfg_row_num ( I_cfg_win_row_num ),
    .I_frame_start ( I_frame_start ),
    .I_frame_end   ( I_frame_end ),
    .I_row_end     ( I_row_end ),
    .I_burst_start ( I_burst_start ),
    .I_burst_row   ( I_burst_row ),
    .I_burst_col   ( I_burst_col ),
    .I_pixel_en    ( I_pixel_en ),
    .I_pixel_data  ( I_pixel_data/*8'hff*/),
    .O_line_start  ( line_start ),
    .O_line_end    ( line_end ),
    .O_line_num    ( line_num ),
    .O_pixel_valid ( pixel_valid ),
    .O_pixel_col   ( pixel_col ),
    .O_pixel_gray  ( pixel_gray )
);/*}}}*/

// cxy_port_offset
cxy_port_offset port_offset (/*{{{*/
    .I_sclk             (I_sclk             ),
    .I_rst_n            (I_rst_n            ),
                                            
    .I_cfg_port_height  (I_cfg_port_height  ),
    .O_port_map_rden    (O_port_map_rden    ),
    .O_port_map_addr    (O_port_map_addr    ),
    .I_port_map_q       (I_port_map_q       ),
                                            
    .I_line_start       (line_start         ),
    .I_line_end         (line_end           ),
    .I_line_num         (line_num           ),
    .I_pixel_valid      (pixel_valid        ),
    .I_pixel_col        (pixel_col          ),
    .I_pixel_gray       (pixel_gray         ),

    .O_line_start       (line_start_2       ),
    .O_line_end         (line_end_2         ),
    .O_line_num         (line_num_2         ),
    .O_pixel_valid      (pixel_valid_2      ),
    .O_pixel_col        (pixel_col_2        ),
    .O_pixel_gray       (pixel_gray_2       )
    );/*}}}*/

// line_buf
rgb_line_buf lb (/*{{{*/
    .I_sclk         ( I_sclk ),
    .I_rst_n        ( I_rst_n ),
    .I_frame_start  ( I_frame_start ),

`ifdef ENABLE_HUB_PORT_OFFSET
    .I_line_start   ( line_start_2 ),
    .I_line_end     ( line_end_2 ),
    .I_line_num     ( line_num_2 ),
    .I_pixel_valid  ( pixel_valid_2 ),
    .I_pixel_col    ( pixel_col_2 ),
    .I_pixel_gray   ( pixel_gray_2/*24'hffffff */),
`else
    .I_line_start   ( line_start ),
    .I_line_end     ( line_end ),
    .I_line_num     ( line_num ),
    .I_pixel_valid  ( pixel_valid ),
    .I_pixel_col    ( pixel_col ),
    .I_pixel_gray   ( pixel_gray ),
`endif

    .O_row_start    ( row_start ),
    .O_row_num      ( row_num ),
    .O_row_ready    ( row_ready ),
    .I_row_ack      ( row_ack ),
    .I_pixel_req    ( pixel_req ),
    .I_pixel_addr   ( pixel_addr ),
    .O_pixel_data   ( pixel_data )
    
);/*}}}*/

// pixel_save_ctrl
rgb_pixel_save_ctrl ctrl (/*{{{*/
    .I_sclk             ( I_sclk ),
    .I_rst_n            ( I_rst_n ),
    .I_frame_start      ( I_frame_start ),
    .I_cfg_box_dir      ( I_cfg_box_dir ),
    .I_cfg_sector_count ( I_cfg_sector_count ),
    .I_cfg_sector_width ( I_cfg_sector_width ),
    .I_cfg_win_col_num  (I_cfg_win_col_num),
    .O_decode_req       ( O_decode_req ),
    .O_decode_row       ( O_decode_row ),
    .O_decode_sector    ( O_decode_sector ),
    .I_decode_done      ( I_decode_done ),
    .I_decode_addr      ( I_decode_addr ),
    
    .O_decode_col_addr  ( O_decode_col_addr ),
    .I_decode_col_addr  ( I_decode_col_addr ),
    
    .I_row_start        ( row_start ),
    .I_row_num          ( row_num ),
    .I_row_ready        ( row_ready ),
    .O_row_ack          ( row_ack ),
    .O_pixel_req        ( pixel_req ),
    .I_pixel_data       ( pixel_data ),
    
    .O_pixel_addr       ( pixel_addr ),
    
    .O_write_valid      ( write_valid   ),
    
    .O_write_start      ( write_start ),
    .I_write_busy       ( write_busy ),
    .O_write_addr       ( write_addr ),
    .O_write_len        ( write_len ),
    .O_write_data       ( write_data )


);/*}}}*/

// pixel_writer
rgb_pixel_writer writer (/*{{{*/
    .I_sclk             ( I_sclk ),
    .I_sdram_clk        ( I_sdram_clk ),
    .I_rst_n            ( I_rst_n ),
    
    .I_write_req        ( write_start ),
    .O_write_busy       ( write_busy ),
    .I_write_addr       ( write_addr ),
    .I_write_len        ( write_len ),
    .I_write_valid      ( write_valid ),
    .I_write_data       ( write_data ),
    
    .O_mux_req          ( O_write_sdram_req ),
    .I_mux_ack          ( I_write_sdram_ack ),
    .I_mux_irq          ( I_write_sdram_irq ),
    .O_mux_cs_n         ( O_write_sdram_cs_n ),
    .O_mux_ras_n        ( O_write_sdram_ras_n ),
    .O_mux_cas_n        ( O_write_sdram_cas_n ),
    .O_mux_we_n         ( O_write_sdram_we_n ),
    .O_mux_ba           ( O_write_sdram_ba ),
    .O_mux_addr         ( O_write_sdram_addr ),
    .O_mux_dq_out       ( O_write_sdram_dq_out ),
    .I_mux_dq_in        ( I_write_sdram_dq_in ),
    .O_mux_dq_oe        ( O_write_sdram_dq_oe ),
    .O_mux_dqm          ( O_write_sdram_dqm )

);/*}}}*/

assign O_decode_buf_sel = I_frame_id;

//------------------------Body---------------------------
endmodule

`default_nettype wire

// vim:set ts=4 sw=4 et fenc=utf-8 fdm=marker:
